package com.jsb.laundry.controller;

import com.alibaba.fastjson.JSONObject;
import com.jsb.laundry.common.constant.CommonConstants;
import com.jsb.laundry.common.design_service.pay.PayStrategy;
import com.jsb.laundry.common.design_service.pay.enums.PayModeEnum;
import com.jsb.laundry.common.design_service.pay.properties.WechatMiniPayProperties;
import com.jsb.laundry.common.design_service.pay.strategy.PayContext;
import com.jsb.laundry.common.enums.ReturnStatusCode;
import com.jsb.laundry.common.exception.BusinessException;
import com.jsb.laundry.common.response.WebResponse;
import com.jsb.laundry.common.utils.JSBUtil;
import com.jsb.laundry.common.utils.redis.RedisUtil;
import com.jsb.laundry.common.utils.spring.SpringUtil;
import com.jsb.laundry.dao.OrderDao;
import com.jsb.laundry.model.dto.PayModeRequest;
import com.jsb.laundry.model.dto.ProductInfoMapDto;
import com.jsb.laundry.model.entity.CouponUserBag;
import com.jsb.laundry.model.vo.PrePayVo;
import com.jsb.laundry.service.OrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Api(tags = {"聚洗衣支付服务"})
@RestController
@RequestMapping("/userPay")
public class PayController {

    private static final Logger LOGGER = LoggerFactory.getLogger(PayController.class);

    @Resource
    private OrderService orderService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private OrderDao orderDao;

    @Resource
    private PayContext payContext;

    @Resource
    private Environment environment;

    /**
     * 统一支付接口
     *
     * @param payModeRequest
     * @return
     */
    @ApiOperation(value = "支付", notes = "支付返回签名串", httpMethod = "POST")
    @PostMapping("/pay")
    public WebResponse<PrePayVo> pay(@RequestBody PayModeRequest payModeRequest) {
        String payMode = payModeRequest.getPayMode();
        String userId = payModeRequest.getUserId();
        String orderId = payModeRequest.getOrderId();

        //参数判空
        if (JSBUtil.isEmptyString(payMode) || JSBUtil.isEmptyString(userId) || JSBUtil.isEmptyString(orderId)) {
            return WebResponse.failOfParameter();
        }

        Boolean supportMode = PayModeEnum.supportEnum(payMode);
        if (!supportMode) {
            return WebResponse.success(ReturnStatusCode.CURRENT_NOT_SUPPORT_SERVICE.getCode(), ReturnStatusCode.CURRENT_NOT_SUPPORT_SERVICE.getMsg());
        }
        PayStrategy payStrategy = SpringUtil.getBean(payMode);
        payContext.setPayStrategy(payStrategy); //切换到对应的策略对象

        //获取实际支付金额
        Object cacheObject = redisUtil.getCacheObject(CommonConstants.TIMEOUT30_WAIT_PAY_ORDER + orderId);
        ProductInfoMapDto payInfo = JSONObject.parseObject(JSONObject.toJSONString(cacheObject), ProductInfoMapDto.class);
        if (JSBUtil.isEmptyObject(payInfo)) {
            throw new BusinessException(ReturnStatusCode.ORDER_LOSE_EFFICACY);
        }
        int total = payInfo.getTotal();

        /**
         * TODO 激活dev配置文件时支付0.01
         */
        String activeProfile = environment.getActiveProfiles()[0];
        if ("dev".equals(activeProfile)) {
            total = 1;
        }

        //校验优惠券是否被使用 !JSBUtil.isEmptyObject(couponInfo.getUseTime()
        if (!JSBUtil.isEmptyString(payInfo.getCouponCardId())) {
            CouponUserBag couponInfo = orderDao.getCouponUseStatus(payInfo.getCouponCardId());
            if (couponInfo == null || !JSBUtil.isEmptyObject(couponInfo.getUseTime())) { //优惠券被使用
                throw new BusinessException(ReturnStatusCode.COUPON_USERD);
            }
        }

        /**
         * 调用支付服务,实现具体策略
         */

        Map<String, String> attachMap = new HashMap();
        attachMap.put("productType", payInfo.getProductType());
        attachMap.put(WechatMiniPayProperties.callbackUrl, payInfo.getCallbackUrl());
        String paySignature = payContext.pay(userId, orderId, total, JSONObject.toJSONString(attachMap));

        PrePayVo prePay = new PrePayVo();
        prePay.setOrderId(orderId).setPrepaySignature(paySignature).setUserId(userId);
        return WebResponse.successData(prePay);
    }


}
